/**
 * Copyright (c) 2017,安徽皖通科技股份有限公司 All rights reserved.
 *
 * @data:2017年10月15日
 * @author:MaShibo
 */
package com.wttech.dzzf.process.service.user;

import com.wtkj.vo.dzzf.base.kfwd.CardInfo;
import com.wtkj.vo.dzzf.base.kfwd.FundAccount;
import com.wtkj.vo.dzzf.share.staticvalue.CertifiType;
import com.wttech.dzzf.process.constant.UserConstants;
import com.wttech.dzzf.process.dao.RepeatUserInfoDao;
import com.wttech.dzzf.process.dao.TransferUserInfoDao;
import com.wttech.dzzf.process.model.CertKey;
import com.wttech.dzzf.process.model.Organization;
import com.wttech.dzzf.process.model.user.User;
import com.wttech.dzzf.process.util.BusinessUtils;
import com.wttech.sjhj.check.moduleSet.CheckUserUpload_8;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;

import static com.wttech.dzzf.process.constant.UserConstants.*;

/**
 * 重复证件号客户信息处理
 *
 * @author MaShibo
 * @date 2017年10月15日
 */
@Service
public class RepeatUserInfosCreatorSerivice {


    private static final Logger LOGGER = LoggerFactory.getLogger(RepeatUserInfosCreatorSerivice.class);

    /**
     * 统一社会信用代码编号
     */
    private static final int CREDIT_CODE_VALUE = 102;

    @Resource
    private RepeatUserInfoDao repeatUserInfoDao;

    @Resource
    private TransferUserInfoDao transferUserInfoDao;


    @Resource
    private UserDetailInfosCreatorService userDetailInfosCreatorService;

    @Resource
    private ThreadPoolTaskExecutor executor;

//    @PostConstruct
    public void buildSeqNoMap() {
        try {
            userDetailInfosCreatorService.setSeqNoMap(repeatUserInfoDao.queryUserSeqNoMap());
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
        }
    }


    /**
     * 异步处理重复数据
     */
    private void asynProcessAbNormalData() {
        List<CertKey> certKeys = repeatUserInfoDao.queryAllRepeatCertInfos();
        int total = certKeys.size();
        LOGGER.info("共{}个重复的证件信息待处理", total);
        List<Future<Void>> futures = new ArrayList<>();
        certKeys.forEach(certKey -> futures.add(executor.submit(() -> processSingleCert(certKey))));
        userDetailInfosCreatorService.getFutureResult(futures);
        LOGGER.info("重复证件号客户信息处理完毕");
        executor.shutdown();
    }

    /**
     * 处理单个证件信息
     *
     * @param certKey 证件信息
     * @return 空
     */
    private Void processSingleCert(CertKey certKey) {
        String certifiNo = certKey.getCertifiNo();
        Integer certifiType = certKey.getCertifiType();
        LOGGER.info("正在处理重复证件号【{}】 - 证件类型【{}】", certifiNo, certifiType);
        List<FundAccount> accounts = repeatUserInfoDao.queryFundAccountByCertInfo(certifiNo, certifiType);
        if (certifiType == CertifiType.ORGCODE || certifiType == CREDIT_CODE_VALUE) {
            LOGGER.info("作为单位用户处理");
            processCompanyInfo(accounts);
        } else {
            LOGGER.info("作为个人用户处理");
            processUseriInfo(accounts);
        }
        return null;
    }


    private void processUseriInfo(List<FundAccount> accounts) {
        FundAccount first = accounts.get(0);
        User user = buildUserInfo(first, OLD_OWNERTYPE_USER);
        for (FundAccount account : accounts) {
            // 查询卡片信息
            List<CardInfo> cardInfos = transferUserInfoDao.queryCardInfosByFundAccount(account.getFundAccountId());
            if (cardInfos.isEmpty()) {
                continue;
            }
            cardInfos.forEach(cardInfo -> userDetailInfosCreatorService.dealWithCard(user, cardInfo));
        }
        userDetailInfosCreatorService.createUserInfo(user);
    }

    public User buildUserInfo(FundAccount first, Integer ownerType) {
        if (first.getClientOprDt() == null) {
            first.setClientOprDt(userDetailInfosCreatorService.getDefaultDate());
        }
        String userId = userDetailInfosCreatorService.buildUserId(first.getClientOprDt());
        String ymd = userId.substring(6, 12);
        try {
            first.setClientOprDt(DateUtils.parseDate(ymd, new String[]{DEFAULT_DATE_PATTERN}));
        } catch (ParseException e2) {
            LOGGER.error(e2.getMessage(), e2);
        }
        String channelId;
        Organization org = transferUserInfoDao.queryOrganizationByNo(first.getClientNO());
        if (org == null || StringUtils.isBlank(org.getChannelId())) {
            channelId = DEFAULT_CHANNELID;
        } else {
            channelId = org.getChannelId();
        }

        User user = new User();
        user.setId(userId);

        user.setUserType(ownerType == OLD_OWNERTYPE_USER ? DEFAULT_USER_USERTYPE : DEFAULT_COMPANY_USERTYPE);

        String userName = first.getFundAccountName();
        user.setUserName(BusinessUtils.regularString(userName));

        Integer userIdType = BusinessUtils.convertUserIdType(first.getCertifiType(), ownerType);
        user.setUserIdType(userIdType);

        String userIdNum = BusinessUtils.regularString(first.getCompanyLic());
        if (!BusinessUtils.containsChineseWords(userIdNum)) {
            user.setUserIdNum(userIdNum);
        } else {
            user.setUserIdNum(DEFAULT_AGENTIDNUM);
        }

        String tel = StringUtils.isBlank(first.getPhone()) ? first.getMobile() : first.getPhone();
        if (StringUtils.equalsIgnoreCase(CheckUserUpload_8.checkTel(tel), RIGHT)) {
            user.setTel(tel);
        } else {
            user.setTel(DEFAULT_TEL);
        }
        first.setPhone(tel);

        //不符合规范的地址使用默认地址
        String address = BusinessUtils.regularString(first.getAddress());
        user.setAddress(StringUtils.equalsIgnoreCase(CheckUserUpload_8.checkAddress(address), RIGHT) ? address : DEFAULT_USER_ADDRESS);

        user.setRegisteredType(REGISTEREDTYPE_OFFLINE);
        user.setChannelId(channelId);
        user.setRegisteredTime(DateFormatUtils.ISO_DATETIME_FORMAT.format(first.getClientOprDt()));
        user.setStatusChangeTime(user.getRegisteredTime());
        if(user.getUserType() == DEFAULT_COMPANY_USERTYPE){
            String agentName = StringUtils.isBlank(first.getRelationName()) ? user.getUserName() : first.getRelationName();
            user.setAgentName(BusinessUtils.regularString(agentName));

            user.setAgentIdType(BusinessUtils.convertUserIdType(first.getAgentIdType(), OLD_OWNERTYPE_USER));
            String agentIdNum = BusinessUtils.regularString(first.getAgentIdNum());
            try {
                if (StringUtils.equalsIgnoreCase(CheckUserUpload_8.checkUserUpload(AGENTIDNUM_STR, agentIdNum), RIGHT)) {
                    user.setAgentIdNum(agentIdNum);
                } else {
                    user.setAgentIdNum(DEFAULT_AGENTIDNUM);
                }
            } catch (ParseException e) {
                LOGGER.debug(e.getMessage(), e);
            }
        }
        //默认正常状态
        user.setStatus(1);
        user.setOperation(ADD_OPERATION);
        return user;
    }


    private void processCompanyInfo(List<FundAccount> accounts) {

        Map<String, Integer> departNoMap = new HashMap<>(accounts.size());
        for (FundAccount account : accounts) {
            User user = buildUserInfo(account, OLD_OWNERTYPE_COMPANY);
            // 设置部门名称
            String seqStr = (StringUtils.isBlank(account.getTopClass()) ? "6101" : account.getTopClass()) + account.getAccountType();
            if (!departNoMap.containsKey(seqStr)) {
                departNoMap.put(seqStr, 1);
            } else {
                int seqNo = departNoMap.get(seqStr);
                departNoMap.put(seqStr, seqNo + 1);
            }
            String department = seqStr + departNoMap.get(seqStr);
            user.setDepartment(department);

            // 查询卡片信息
            List<CardInfo> cardInfos = transferUserInfoDao.queryCardInfosByFundAccount(account.getFundAccountId());
            if (cardInfos.isEmpty()) {
                continue;
            }
            cardInfos.forEach(cardInfo -> userDetailInfosCreatorService.dealWithCard(user, cardInfo));
            userDetailInfosCreatorService.createUserInfo(user);
        }
    }

    public class SubProcessThread implements Callable<Void> {


        private int count;

        private String certifiNo;

        private Integer certifiType;

        /**
         * @param count       第几次执行
         * @param certifiNo   证件号
         * @param certifiType 证件类型
         */
        SubProcessThread(int count, String certifiNo, Integer certifiType) {
            this.count = count;
            this.certifiNo = certifiNo;
            this.certifiType = certifiType;
        }

        @Override
        public Void call() throws Exception {
            LOGGER.info("第{}次开始执行", count);
            List<FundAccount> accounts = repeatUserInfoDao.queryFundAccountByCertInfo(certifiNo, certifiType);
            if (certifiType == CertifiType.ORGCODE) {
                processCompanyInfo(accounts);
            } else {
                processUseriInfo(accounts);
            }
            LOGGER.info("第{}次执行结束", count);
            return null;
        }

    }

    public static void main(String[] args) {
        @SuppressWarnings("resource")
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        RepeatUserInfosCreatorSerivice serivice = context.getBean(RepeatUserInfosCreatorSerivice.class);
        serivice.asynProcessAbNormalData();
    }

}
